As a tourist I want to make the most of the time in the city of Melbourne and have a more enjoyable and fulfilling experience.
When visiting Melbourne, tourists are often eager to uncover new and exciting places to visit, in order to add depth and interest to their itinerary. By researching lesser-known attractions or asking locals for recommendations, travelers can discover hidden gems that may not have been on their radar initially. Additionally, it's important to plan one's route effectively in order to avoid wasting time and money on unnecessary transportation. By mapping out a logical itinerary, visitors can ensure that they are able to see as much of the city as possible within their allotted time frame, without missing out on any must-see sights.
As a cafe, restaurant, or bistro owner in Melbourne, I understand the value of catering to tourists who are looking to make the most of their time in the city. By recognizing and responding to the needs and interests of visitors, I can build a loyal customer base and create a sustainable business model that benefits both myself and the local tourism industry.
The primary objective of business owners is to enhance customer engagement and drive revenue growth by delivering an exceptional and unforgettable experience to visitors. This can result in a surge of foot traffic and revenue generation for the cafe, restaurant, and bistro owners. In the end, the aim of business owners is to develop a feasible business model that not only serves their best interests but also provides substantial benefits to their customers and the neighboring community.
At the end of this use case you will:
Melbourne is known for its vibrant arts and culture scene, with numerous museums, galleries, and theaters. The city is also famous for its food and wine culture, with a diverse range of restaurants, cafes, and bars.It has a thriving coffee culture and is known for its brunch spots. Overall, Melbourne offers a unique combination of culture, food, nature, and sports, making it a popular destination for tourists from around the world.
The objective of this use case is to offer tourists a comprehensive overview of the popular tourist spots and interesting locations in Melbourne, coupled with valuable insights to help them organize their trip effectively. By displaying the attractions on a map, visitors can effortlessly determine their location and proximity to one another, which makes planning their itinerary and optimizing their time in Melbourne a more convenient task. Through the information and guidance provided for each attraction, tourists can make informed decisions regarding which places to visit, which helps them avoid potential disappointments.
Moreover, this use case also benefits the nearby cafes, restaurants, and bistros owners as they will be featured on the map along with the landmarks, leading to an increase in revenue and customer footfall for their establishments.
Contents
# Standard
import os
import json
# Data import
import requests
# Data manipulation
import pandas as pd
# Plotting
import plotly.graph_objs as go
import plotly.express as px
import folium
import folium.plugins as plugins
# Landmarks and places of interest data
lan_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/landmarks-and-places-of-interest-including-schools-theatres-health-services-spor/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(lan_url)
response = r.json()
lan_data = pd.DataFrame(response)
# Public artworks, fountains and monuments data
pub_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/public-artworks-fountains-and-monuments/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(pub_url)
response = r.json()
pub_data = pd.DataFrame(response)
# Public memorials and sculptures data
mem_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/public-memorials-and-sculptures/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(mem_url)
response = r.json()
mem_data = pd.DataFrame(response)
# Cafe, restaurant and bistro seats data
cafe_url = 'https://data.melbourne.vic.gov.au/api/v2/catalog/datasets/cafes-and-restaurants-with-seating-capacity/exports/json?limit=-1&offset=0&timezone=UTC'
r = requests.get(cafe_url)
response = r.json()
cafe_data = pd.DataFrame(response)
Next, we will look at one specific dataset to better understand its structure and how we can use it. For this exercise, we will observe the Landmarks and places of interest dataset, specifically, it's first ten rows.
# Print details of data
print(f'The shape of the dataset is:{lan_data.shape}')
print()
print('The first ten rows of this dataset are:')
# Print the first 10 rows of data
lan_data.head(10)
The shape of the dataset is:(242, 4) The first ten rows of this dataset are:
| theme | sub_theme | feature_name | co_ordinates | |
|---|---|---|---|---|
| 0 | Place of Worship | Church | St Francis Church | {'lon': 144.962422614541, 'lat': -37.811884783... |
| 1 | Place of Worship | Church | St James Church | {'lon': 144.952468571683, 'lat': -37.810128120... |
| 2 | Place of Worship | Church | St Mary's Anglican Church | {'lon': 144.953761537074, 'lat': -37.803166367... |
| 3 | Place of Worship | Church | Scots Church | {'lon': 144.96855105335, 'lat': -37.8145687802... |
| 4 | Place of Worship | Church | St Michael's Uniting Church | {'lon': 144.969174036096, 'lat': -37.814385132... |
| 5 | Place of Worship | Church | Greek Orthodox Church | {'lon': 144.978259089269, 'lat': -37.808806466... |
| 6 | Place of Worship | Church | North Melbourne Uniting | {'lon': 144.947671538375, 'lat': -37.803553847... |
| 7 | Place of Worship | Church | South Yarra Presbyterian Church | {'lon': 144.98562699348, 'lat': -37.8407473645... |
| 8 | Place of Worship | Synagogue | East Melbourne Synagogue | {'lon': 144.97422190954, 'lat': -37.809113728917} |
| 9 | Transport | Transport Terminal | Port of Melbourne | {'lon': 144.91753432375, 'lat': -37.8137384362... |
We can see that there are 242 records and 4 fields describing each record.
Each record can be broken down into the following fields:
theme: Main Theme of the landmark. e.g. Places of Interest.
sub_theme: Exact Identification of the landmark. e.g Church or Synagogue.
feature_name: Name of the landmark. e.g. St Francis Church, East Melbourne Synagogue.
co_ordinates: Data regarding the geographical location of a place, determined by its latitude and longitude.
Awesome! After taking a look at one of the Melbourne datasets we can see the overall structure and contents. Lets now begin our analysis of each individual dataset.
We are now going analyse each individual dataset so we can generate useful information and visualisations about them. This will assist us when producing final interactive maps and predictions later on.
Let's first review the dataset by displaying the first five rows of the dataset.
lan_data.head(5)
| theme | sub_theme | feature_name | co_ordinates | |
|---|---|---|---|---|
| 0 | Place of Worship | Church | St Francis Church | {'lon': 144.962422614541, 'lat': -37.811884783... |
| 1 | Place of Worship | Church | St James Church | {'lon': 144.952468571683, 'lat': -37.810128120... |
| 2 | Place of Worship | Church | St Mary's Anglican Church | {'lon': 144.953761537074, 'lat': -37.803166367... |
| 3 | Place of Worship | Church | Scots Church | {'lon': 144.96855105335, 'lat': -37.8145687802... |
| 4 | Place of Worship | Church | St Michael's Uniting Church | {'lon': 144.969174036096, 'lat': -37.814385132... |
Renaming the columns for better user experience
lan_data = lan_data.rename(columns={'sub_theme':'Landmark','feature_name': 'name'})
The next step is to extract the latitute and Longitude from the 'co-ordinates' column
# split the coordinates column into separate latitude and longitude columns
lan_data[['longitude', 'latitude']] = lan_data['co_ordinates'].apply(lambda x: pd.Series(eval(str(x))))
Let us drop the redundant columns
lan_data=lan_data.drop(['co_ordinates'], axis = 1)
Let's Visualize Number of Features by Theme.
# Group the data by theme and count the number of features
df_grouped = lan_data.groupby('theme').size().reset_index(name='count')
# Create a bar plot
fig = px.bar(df_grouped, x='theme', y='count', color='theme', color_discrete_sequence=px.colors.qualitative.Safe)
# Set the title and axis labels
fig.update_layout(title_text='Number of Features by Theme', xaxis_title='Theme', yaxis_title='Count')
# Show the plot
fig.show()
Preview of the Cleaned Landmark Dataset
lan_data.head(2)
| theme | Landmark | name | longitude | latitude | |
|---|---|---|---|---|---|
| 0 | Place of Worship | Church | St Francis Church | 144.962423 | -37.811885 |
| 1 | Place of Worship | Church | St James Church | 144.952469 | -37.810128 |
The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.
Let's first review the dataset by displaying the first five rows of the dataset.
pub_data.head(5)
| asset_type | name | xorg | xsource | address_point | artist | alternate_name | art_date | mel_way_ref | respective_author | structure | co_ordinates | easting | northing | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Art | Blowhole | Beveridge Williams Surveyors | Field Survey | 13 Harbour Esplanade, DOCKLANDS | Duncan Stemler | None | 2005 | 2E_G8 | City of Melbourne | Stainless-steel and aluminium sculpture | {'lon': 144.946871022845, 'lat': -37.822018216... | 319296.29200 | 5.811946e+06 |
| 1 | Art | Bandstand | City of Melbourne | MCC - Ortho Image March 2005 - Final | 200 Little Collins Street, MELBOURNE | George Dodd | None | 1864 | 2F_G3 | City Of Melbourne | Concrete bandstand | {'lon': 144.96733868317, 'lat': -37.8140548689... | 321078.68900 | 5.812869e+06 |
| 2 | Art | Federation Bells | City of Melbourne | MCC - Ground Ortho Image March 2008 | Birrarung Marr, MELBOURNE | Designers Neil McLachlan and Anton Hasell | None | 2002 | 2F_ K6 | City of Melbourne | Bronze-alloy bells on galvanised-steel poles | {'lon': 144.974167165492, 'lat': -37.818673886... | 321690.93246 | 5.812370e+06 |
| 3 | Art | Coat of Arms | City of Melbourne | MCC - Ortho Image March 2005 - Final | 98 Swanston Street, MELBOURNE | City of Melbourne | None | 1992 | 2F_F4 | City Of Melbourne | Brass pavement inlay | {'lon': 144.966495940551, 'lat': -37.815158293... | 321007.16500 | 5.812745e+06 |
| 4 | Monument | Edmund Fitzgibbon Memorial | City of Melbourne | MCC - Ortho Image March 2005 - Final | 208 St Kilda Road, SOUTHBANK | James White | None | 1908 | 2F_H9 | City Of Melbourne | Bronze statue with Harcourt granite pedestal | {'lon': 144.970418561306, 'lat': -37.823612211... | 321372.86300 | 5.811815e+06 |
Let us drop the redundant columns
pub_data.drop(columns=['xorg', 'xsource', 'address_point', 'alternate_name', 'mel_way_ref', 'respective_author', 'easting', 'northing'], inplace=True)
pub_data
| asset_type | name | artist | art_date | structure | co_ordinates | |
|---|---|---|---|---|---|---|
| 0 | Art | Blowhole | Duncan Stemler | 2005 | Stainless-steel and aluminium sculpture | {'lon': 144.946871022845, 'lat': -37.822018216... |
| 1 | Art | Bandstand | George Dodd | 1864 | Concrete bandstand | {'lon': 144.96733868317, 'lat': -37.8140548689... |
| 2 | Art | Federation Bells | Designers Neil McLachlan and Anton Hasell | 2002 | Bronze-alloy bells on galvanised-steel poles | {'lon': 144.974167165492, 'lat': -37.818673886... |
| 3 | Art | Coat of Arms | City of Melbourne | 1992 | Brass pavement inlay | {'lon': 144.966495940551, 'lat': -37.815158293... |
| 4 | Monument | Edmund Fitzgibbon Memorial | James White | 1908 | Bronze statue with Harcourt granite pedestal | {'lon': 144.970418561306, 'lat': -37.823612211... |
| ... | ... | ... | ... | ... | ... | ... |
| 256 | Art | Car Nuggets | Patricia Piccinini | 2006 | Sculptural forms | {'lon': 144.949169769731, 'lat': -37.821738462... |
| 257 | Art | Car Nuggets | Patricia Piccinini | 2006 | Sculptural forms | {'lon': 144.949168740276, 'lat': -37.821724474... |
| 258 | Art | Scar - A Stolen Vision | Karen Casey, Craig Charles, Glenn Romanis, Mar... | 2001 | Wooden pier post and metal sculptures | {'lon': 144.959252201884, 'lat': -37.820154739... |
| 259 | Monument | Sir John Monash | William Leslie Bowles | 1950 | Bronze statue on granite plinth | {'lon': 144.97275207638, 'lat': -37.8267733497... |
| 260 | Art | Scar - A Stolen Vision | Karen Casey, Craig Charles, Glenn Romanis, Mar... | 2001 | Wooden pier post and metal sculptures | {'lon': 144.959477986287, 'lat': -37.820104643... |
261 rows × 6 columns
The next step is to extract the latitute and Longitude from the 'co-ordinates' column
pub_data[['longitude', 'latitude']] = pub_data['co_ordinates'].apply(lambda x: pd.Series(eval(str(x))))
pub_data=pub_data.drop(['co_ordinates'], axis = 1)
Renaming the columns for better user experience
pub_data = pub_data.rename(columns={'asset_type': 'Landmark', 'art_date':'year', 'structure': 'description'})
Let's Visualize Landmarks by Percentage
# Group by asset type and count the number of occurrences
grouped = pub_data.groupby("Landmark").size().reset_index(name="count")
# Create a pie chart
fig = px.pie(grouped, values="count", names="Landmark")
# Show the chart
fig.show()
pub_data.head(3)
| Landmark | name | artist | year | description | longitude | latitude | |
|---|---|---|---|---|---|---|---|
| 0 | Art | Blowhole | Duncan Stemler | 2005 | Stainless-steel and aluminium sculpture | 144.946871 | -37.822018 |
| 1 | Art | Bandstand | George Dodd | 1864 | Concrete bandstand | 144.967339 | -37.814055 |
| 2 | Art | Federation Bells | Designers Neil McLachlan and Anton Hasell | 2002 | Bronze-alloy bells on galvanised-steel poles | 144.974167 | -37.818674 |
The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.
Let's first review the dataset by displaying the first five rows of the dataset.
mem_data.head(5)
| description | title | co_ordinates | |
|---|---|---|---|
| 0 | Arts & Heritage - Memorials - Fountain | Coles Fountain | {'lon': 144.973483970263, 'lat': -37.809770639... |
| 1 | Arts & Heritage - Memorials - Sculpture | World War 1 Memorial | {'lon': 144.958086476511, 'lat': -37.791550224... |
| 2 | Arts & Heritage - Sculpture - Memorial | Sir Edward "Weary" Dunlop | {'lon': 144.971594258329, 'lat': -37.825309803... |
| 3 | Arts & Heritage - Sculpture - Sculpture | The Travellers | {'lon': 144.962960549385, 'lat': -37.820079378... |
| 4 | Arts & Heritage - Memorials - Garden/Sculpture | Pioneer Women's Memorial | {'lon': 144.976076236026, 'lat': -37.825114779... |
Extract the second word after '-' from the 'description' column
mem_data['Landmark'] = mem_data['description'].str.split('-').str[1]
mem_data['Landmark'].unique()
array([' Memorials ', ' Sculpture ', ' Aurora Sculpture ', ' Memorial',
' Federation Bells ', ' Fountain', ' Indigenous',
' Speakers Corner ', ' Horology ', ' Unknown', '',
' Artwork Commission '], dtype=object)
As we can see, we have extracted the keyword "Landmark" from the description column and stored it as "Landmark" column in the dataset
The next step is to extract the latitute and Longitude from the 'co-ordinates' column
# Convert the 'co_ordinates' column to string datatype
mem_data['co_ordinates'] = mem_data['co_ordinates'].astype(str)
# Extract the latitude and longitude values from the 'co_ordinates' column
mem_data[['longitude', 'latitude']] = mem_data['co_ordinates'].apply(eval).apply(pd.Series)[['lon', 'lat']]
Longitute and Latitute have been extracted from the 'co_ordinates' column, we can go forward and remove the redundant columns from our dataset and Renaming them for better user experience
# Drop the redundant columns
mem_data_new = mem_data.drop(['co_ordinates'], axis=1)
# Renaming the 'title' column to 'name'
mem_data_new = mem_data_new.rename(columns={'title': 'name'})
mem_data_new.head(5)
| description | name | Landmark | longitude | latitude | |
|---|---|---|---|---|---|
| 0 | Arts & Heritage - Memorials - Fountain | Coles Fountain | Memorials | 144.973484 | -37.809771 |
| 1 | Arts & Heritage - Memorials - Sculpture | World War 1 Memorial | Memorials | 144.958086 | -37.791550 |
| 2 | Arts & Heritage - Sculpture - Memorial | Sir Edward "Weary" Dunlop | Sculpture | 144.971594 | -37.825310 |
| 3 | Arts & Heritage - Sculpture - Sculpture | The Travellers | Sculpture | 144.962961 | -37.820079 |
| 4 | Arts & Heritage - Memorials - Garden/Sculpture | Pioneer Women's Memorial | Memorials | 144.976076 | -37.825115 |
The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.
Let's first review the dataset by displaying the first five rows of the dataset.
cafe_data.head(5)
| census_year | block_id | property_id | base_property_id | building_address | clue_small_area | business_address | trading_name | industry_anzsic4_code | industry_anzsic4_description | seating_type | number_of_seats | longitude | latitude | location | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2014 | 31 | 102109 | 102109 | 612-624 Collins Street MELBOURNE 3000 | Melbourne (CBD) | Ground , 618B Collins Street MELBOURNE 3000 | Choix Creperie Cafe | 4511 | Cafes and Restaurants | Seats - Outdoor | 2 | 144.95435 | -37.81868 | {'lon': 144.95435, 'lat': -37.81868} |
| 1 | 2014 | 31 | 102109 | 102109 | 612-624 Collins Street MELBOURNE 3000 | Melbourne (CBD) | Ground , 618 Collins Street MELBOURNE 3000 | Purple Peanuts Japanese Cafe | 4511 | Cafes and Restaurants | Seats - Indoor | 14 | 144.95435 | -37.81868 | {'lon': 144.95435, 'lat': -37.81868} |
| 2 | 2014 | 31 | 102110 | 102110 | 582-606 Collins Street MELBOURNE 3000 | Melbourne (CBD) | Shop 1, 600 Collins Street MELBOURNE 3000 | Cafe Eurasia | 4511 | Cafes and Restaurants | Seats - Outdoor | 14 | 144.95494 | -37.81850 | {'lon': 144.95494, 'lat': -37.8185} |
| 3 | 2014 | 31 | 102111 | 102111 | 608-610 Collins Street MELBOURNE 3000 | Melbourne (CBD) | Shop 5, 608-610 Collins Street MELBOURNE 3000 | Wonderful Garden | 4512 | Takeaway Food Services | Seats - Outdoor | 5 | 144.95457 | -37.81861 | {'lon': 144.95457, 'lat': -37.81861} |
| 4 | 2014 | 31 | 105942 | 105942 | 585-587 Little Collins Street MELBOURNE 3000 | Melbourne (CBD) | 585 Little Collins Street MELBOURNE 3000 | Hudson & Co | 4512 | Takeaway Food Services | Seats - Indoor | 16 | 144.95544 | -37.81787 | {'lon': 144.95544, 'lat': -37.81787} |
Check for Null Values in Dataset
cafe_data.isnull().sum()
census_year 0 block_id 0 property_id 0 base_property_id 0 building_address 0 clue_small_area 0 business_address 0 trading_name 0 industry_anzsic4_code 0 industry_anzsic4_description 0 seating_type 0 number_of_seats 0 longitude 527 latitude 527 location 527 dtype: int64
Drop the Null values
cafe_data.dropna(inplace = True)
Let us drop the redundant columns and rename some of the columns for better user experience
# Drop redundant Data
cafe_data = cafe_data.drop(['block_id', 'property_id','base_property_id','business_address','clue_small_area',
'industry_anzsic4_code','location'], axis=1)
#Rename some of the columns
cafe_data = cafe_data.rename(columns={'trading_name': 'name','building_address':'address','census_year':'year',
'industry_anzsic4_description':'Industry'})
Drop Duplicate Values based on the column "Name"
cafe_data = cafe_data.drop_duplicates(subset=['name'])
cafe_data
| year | address | name | Industry | seating_type | number_of_seats | longitude | latitude | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2014 | 612-624 Collins Street MELBOURNE 3000 | Choix Creperie Cafe | Cafes and Restaurants | Seats - Outdoor | 2 | 144.95435 | -37.81868 |
| 1 | 2014 | 612-624 Collins Street MELBOURNE 3000 | Purple Peanuts Japanese Cafe | Cafes and Restaurants | Seats - Indoor | 14 | 144.95435 | -37.81868 |
| 2 | 2014 | 582-606 Collins Street MELBOURNE 3000 | Cafe Eurasia | Cafes and Restaurants | Seats - Outdoor | 14 | 144.95494 | -37.81850 |
| 3 | 2014 | 608-610 Collins Street MELBOURNE 3000 | Wonderful Garden | Takeaway Food Services | Seats - Outdoor | 5 | 144.95457 | -37.81861 |
| 4 | 2014 | 585-587 Little Collins Street MELBOURNE 3000 | Hudson & Co | Takeaway Food Services | Seats - Indoor | 16 | 144.95544 | -37.81787 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 56930 | 2021 | 697 Collins Street DOCKLANDS VIC 3008 | Destination Roll | Takeaway Food Services | Seats - Indoor | 7 | 144.95177 | -37.82079 |
| 56940 | 2021 | 829-843 Bourke Street DOCKLANDS VIC 3008 | San Marzano Pizzeria | Takeaway Food Services | Seats - Indoor | 8 | 144.94346 | -37.82045 |
| 56944 | 2021 | Serrata Apartments 813-817 Bourke Street DOCKL... | TOSS'D | Cafes and Restaurants | Seats - Outdoor | 22 | 144.94469 | -37.81995 |
| 56948 | 2021 | 790-814 Collins Street DOCKLANDS VIC 3008 | Poke Bay | Takeaway Food Services | Seats - Indoor | 6 | 144.94583 | -37.82104 |
| 56961 | 2021 | The District Docklands East Car Park 50-94 Wat... | Shall We Coffee | Takeaway Food Services | Seats - Outdoor | 6 | 144.93944 | -37.81215 |
6328 rows × 8 columns
Categorised some of the Industries as "Other", if their total count is less than 150 as they will be of less importance for our analysis
# Compute the value counts of the 'industry_anzsic4_description' column
counts = cafe_data['Industry'].value_counts()
# Replace values that have counts less than 150 with 'Other'
cafe_data.loc[cafe_data['Industry'].isin(counts[counts < 260].index), 'Industry'] = 'Other'
count = cafe_data['Industry'].value_counts()
Created a dataframe which contains the Industry name and the total count in City of Melbourne
# create a new dataframe to store the counts
counts_df = pd.DataFrame(count, count.index).reset_index()
counts_df.columns = ['Industry', 'count']
counts_df
| Industry | count | |
|---|---|---|
| 0 | Cafes and Restaurants | 4544 |
| 1 | Takeaway Food Services | 979 |
| 2 | Other | 418 |
| 3 | Pubs, Taverns and Bars | 387 |
Lets Visualize a Pie Chart for the Industry-Count data.
import plotly.graph_objs as go
# create a pie chart
fig = go.Figure(
go.Pie(
labels=counts_df['Industry'],
values=counts_df['count']
)
)
# set the title
fig.update_layout(title_text='Top Industries by Count')
# show the plot
fig.show()
Final dataset
cafe_data.head(3)
| year | address | name | Industry | seating_type | number_of_seats | longitude | latitude | |
|---|---|---|---|---|---|---|---|---|
| 0 | 2014 | 612-624 Collins Street MELBOURNE 3000 | Choix Creperie Cafe | Cafes and Restaurants | Seats - Outdoor | 2 | 144.95435 | -37.81868 |
| 1 | 2014 | 612-624 Collins Street MELBOURNE 3000 | Purple Peanuts Japanese Cafe | Cafes and Restaurants | Seats - Indoor | 14 | 144.95435 | -37.81868 |
| 2 | 2014 | 582-606 Collins Street MELBOURNE 3000 | Cafe Eurasia | Cafes and Restaurants | Seats - Outdoor | 14 | 144.95494 | -37.81850 |
#cafe_data = cafe_data.head(50)
The dataset has been subjected to pre-processing and Feature Engineering and is now ready for further analysis.
df1_merged = pd.merge(lan_data, pub_data, on=['Landmark', 'name', 'longitude','latitude'],how='outer')
combined_df = pd.merge(df1_merged, mem_data_new, on=['Landmark', 'name', 'longitude','latitude','description'],how='outer')
Fill the null Values with "N.A"
combined_df_cleaned = combined_df.fillna('N.A')
combined_df_cleaned
| theme | Landmark | name | longitude | latitude | artist | year | description | |
|---|---|---|---|---|---|---|---|---|
| 0 | Place of Worship | Church | St Francis Church | 144.962423 | -37.811885 | N.A | N.A | N.A |
| 1 | Place of Worship | Church | St James Church | 144.952469 | -37.810128 | N.A | N.A | N.A |
| 2 | Place of Worship | Church | St Mary's Anglican Church | 144.953762 | -37.803166 | N.A | N.A | N.A |
| 3 | Place of Worship | Church | Scots Church | 144.968551 | -37.814569 | N.A | N.A | N.A |
| 4 | Place of Worship | Church | St Michael's Uniting Church | 144.969174 | -37.814385 | N.A | N.A | N.A |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 661 | N.A | Memorials | Sir William Brunton Drinking Fountain | 144.972179 | -37.789304 | N.A | N.A | Arts & Heritage - Memorials - Drinking Fountain |
| 662 | N.A | Artwork Commission | Maxims of Behaviour | 144.965809 | -37.813602 | N.A | N.A | Art & Heritage Collection - Artwork Commission... |
| 663 | N.A | Sculpture | Another View Site 17 | 144.968381 | -37.814805 | N.A | N.A | Arts & Heritage - Sculpture - Sculpture |
| 664 | N.A | Sculpture | Vault | 144.967733 | -37.826071 | N.A | N.A | Arts & Heritage - Sculpture - Sculpture |
| 665 | N.A | Sculpture | Commonwealth Games Aquatic Sculptures - Eels | 144.924307 | -37.796629 | N.A | N.A | Art and Heritage - Sculpture - Commonwealth Ga... |
666 rows × 8 columns
Remove duplicates based on the column "name"
combined_df_final = combined_df_cleaned.drop_duplicates(subset=['name'])
combined_df_final
| theme | Landmark | name | longitude | latitude | artist | year | description | |
|---|---|---|---|---|---|---|---|---|
| 0 | Place of Worship | Church | St Francis Church | 144.962423 | -37.811885 | N.A | N.A | N.A |
| 1 | Place of Worship | Church | St James Church | 144.952469 | -37.810128 | N.A | N.A | N.A |
| 2 | Place of Worship | Church | St Mary's Anglican Church | 144.953762 | -37.803166 | N.A | N.A | N.A |
| 3 | Place of Worship | Church | Scots Church | 144.968551 | -37.814569 | N.A | N.A | N.A |
| 4 | Place of Worship | Church | St Michael's Uniting Church | 144.969174 | -37.814385 | N.A | N.A | N.A |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 651 | N.A | Memorials | Australian Hellenic Memorial | 144.972974 | -37.827212 | N.A | N.A | Arts & Heritage - Memorials - Memorial |
| 653 | N.A | Sculpture | Nurse Edith Cavell Memorial | 144.973699 | -37.827988 | N.A | N.A | Arts & Heritage - Sculpture - Sculpture |
| 655 | N.A | Memorials | Victoria Police Memorial | 144.970982 | -37.824242 | N.A | N.A | Arts & Heritage - Memorials - Memorial |
| 661 | N.A | Memorials | Sir William Brunton Drinking Fountain | 144.972179 | -37.789304 | N.A | N.A | Arts & Heritage - Memorials - Drinking Fountain |
| 663 | N.A | Sculpture | Another View Site 17 | 144.968381 | -37.814805 | N.A | N.A | Arts & Heritage - Sculpture - Sculpture |
449 rows × 8 columns
Create Dictionary for Custom Icons and Colors for Landmarks and Cafes & Restaurants
icons = {
'Church': {'icon': 'church', 'color': 'blue'},
'Synagogue': {'icon': 'star-of-david', 'color': 'purple'},
'Transport Terminal': {'icon': 'bus', 'color': 'darkblue'},
'Major Sports & Recreation Facility': {'icon': 'futbol', 'color': 'orange'},
'Primary Schools': {'icon': 'graduation-cap', 'color': 'green'},
'Informal Outdoor Facility (Park/Garden/Reserve)': {'icon': 'tree', 'color': 'green'},
'Secondary Schools': {'icon': 'graduation-cap', 'color': 'green'},
'Theatre Live': {'icon': 'ticket', 'color': 'red'},
'Retail/Office': {'icon': 'shopping-cart', 'color': 'gray'},
'Private Hospital': {'icon': 'hospital', 'color': 'red'},
'Government Building': {'icon': 'institution', 'color': 'darkpurple'},
'Railway Station': {'icon': 'train', 'color': 'black'},
'Vacant Land - Undeveloped Site': {'icon': 'ban', 'color': 'gray'},
'Retail/Office/Carpark': {'icon': 'building', 'color': 'gray'},
'Art Gallery/Museum': {'icon': 'image', 'color': 'red'},
'Office': {'icon': 'briefcase', 'color': 'gray'},
'Film & RV Studio': {'icon': 'video-camera', 'color': 'lightblue'},
'Marina': {'icon': 'anchor', 'color': 'blue'},
'Public Hospital': {'icon': 'hospital', 'color': 'red'},
'Hostel': {'icon': 'bed', 'color': 'black'},
'Outdoor Recreation Facility (Zoo, Golf Course)': {'icon': 'paw', 'color': 'green'},
'Public Buildings': {'icon': 'home', 'color': 'darkpurple'},
'Tertiary (University)': {'icon': 'university', 'color': 'darkpurple'},
'Fire Station': {'icon': 'fire-extinguisher', 'color': 'red'},
'Observation Tower/Wheel': {'icon': 'eye', 'color': 'gray'},
'Dwelling (House)': {'icon': 'home', 'color': 'black'},
'Police Station': {'icon': 'shield', 'color': 'red'},
'Private Sports Club/Facility': {'icon': 'futbol', 'color': 'orange'},
'Function/Conference/Exhibition Centre': {'icon': 'briefcase', 'color': 'red'},
'Current Construction Site': {'icon': 'hard-hat', 'color': 'gray'},
'Further Education': {'icon': 'book', 'color': 'darkpurple'},
'Indoor Recreation Facility': {'icon': 'cube', 'color': 'orange'},
'Store Yard': {'icon': 'building', 'color': 'gray'},
'Retail/Office/Residential/Carpark': {'icon': 'home', 'color': 'gray'},
'Gymnasium/Health Club': {'icon': 'heartbeat', 'color': 'orange'},
'Retail/Residential': {'icon': 'home', 'color': 'black'},
'Visitor Centre': {'icon': 'binoculars', 'color': 'gray'},
'Library': {'icon': 'book', 'color': 'purple'},
'Cemetery': {'icon': 'cross', 'color': 'gray'},
'Retail': {'icon': 'shopping-cart', 'color': 'blue'},
'School - Primary and Secondary Education': {'icon': 'graduation-cap', 'color': 'orange'},
'Casino': {'icon': 'diamond', 'color': 'red'},
'Current Construction Site - Commercial': {'icon': 'hard-hat', 'color': 'darkblue'},
'Cinema': {'icon': 'film', 'color': 'green'},
'Industrial (Manufacturing)': {'icon': 'industry', 'color': 'black'},
'Aquarium': {'icon': 'fish', 'color': 'darkgreen'},
'Bridge': {'icon': 'bridge', 'color': 'pink'},
'Department Store': {'icon': 'shopping-bag', 'color': 'cadetblue'},
'Medical Services': {'icon': 'ambulance', 'color': 'lightred'},
'Art': {'icon': 'paint-brush', 'color': 'darkpurple'},
'Monument': {'icon': 'monument', 'color': 'darkgreen'},
'Fountain': {'icon': 'volcano', 'color': 'lightblue'},
' Memorials ': {'icon': 'monument', 'color': 'darkred'},
' Sculpture ': {'icon': 'landmark', 'color': 'purple'},
' Aurora Sculpture ': {'icon': 'snowflake', 'color': 'darkgreen'},
' Memorial': {'icon': 'monument', 'color': 'darkred'},
' Federation Bells ': {'icon': 'music', 'color': 'darkpurple'},
' Indigenous': {'icon': 'leaf', 'color': 'orange'},
' Speakers Corner ': {'icon': 'bullhorn', 'color': 'gray'},
' Horology ': {'icon': 'clock', 'color': 'black'},
' Unknown': {'icon': 'question-circle', 'color': 'gray'},
'': {'icon': 'question-circle', 'color': 'gray'},
' Artwork Commission ': {'icon': 'paint-brush', 'color': 'darkpurple'}
}
icon_cafe = {
'Cafes and Restaurants': {'icon': 'coffee', 'color': 'red'},
'Takeaway Food Services': {'icon': 'utensils', 'color': 'purple'},
'Pubs, Taverns and Bars': {'icon': 'wine-glass', 'color': 'darkblue'},
'Other': {'icon': 'question-circle', 'color': 'black'}
}
Visualizing a Map which Displays the Landmarks and the Cafes,Restaurants and Bars Nearby
# Create a map object centered on Melbourne, Australia
melbourne_map = folium.Map(location=[-37.8136, 144.9631], zoom_start=20, width='100%', height='100%')
marker_group = folium.FeatureGroup(name='Landmarks')
cafe_group = folium.FeatureGroup(name='Cafes')
# Loop through each row in the dataframe
for index, row in combined_df_final.iterrows():
# Get the landmark type for the current row
landmark_type = row['Landmark']
# Check if the landmark type is in the icons dictionary
if landmark_type in icons:
icon = icons[landmark_type]['icon']
color = icons[landmark_type]['color']
# Create a list to store nearby cafes
nearby_cafes = []
# Loop through the cafe data and add nearby cafes to the list
for cafe_index, cafe_row in cafe_data.iterrows():
industry_type = cafe_row['Industry']
if industry_type in icon_cafe:
icons_cafe = icon_cafe[industry_type]['icon']
colors_cafe = icon_cafe[industry_type]['color']
if abs(cafe_row['latitude'] - row['latitude']) < 0.001 and abs(cafe_row['longitude'] - row['longitude']) < 0.001:
nearby_cafes.append(cafe_row['name'])
cafe_marker = folium.Marker(
location=[cafe_row['latitude'], cafe_row['longitude']],
icon=folium.Icon(color= colors_cafe, icon=icons_cafe, prefix='fa'),
popup=folium.Popup(
f"Name: {cafe_row['name']}<br>Address: {cafe_row['address']}<br>Industry: {cafe_row['Industry']}<br>Seating type: {cafe_row['seating_type']}<br>Number of seats: {cafe_row['number_of_seats']}",
max_width=400,
style={
'font-size': '16px',
'line-height': '1.6',
'padding': '10px'
}
),
tooltip=cafe_row['name']
)
cafe_marker.add_to(cafe_group)
# Create a popup HTML string for the landmark
landmark_popup_html = f"Name: {row['name']}<br>Landmark: {row['Landmark']}<br>Description: {row['description']}"
# Check if there are nearby cafes
if len(nearby_cafes) > 0:
# Add nearby cafes to the popup HTML string
landmark_popup_html += "<br><br><b>Nearby Food Outlets:</b><br>"
for cafe in nearby_cafes:
landmark_popup_html += f"{cafe}<br>"
# Create a marker for the landmark
landmark_marker = folium.Marker(
location=[row['latitude'], row['longitude']],
icon = folium.Icon(icon = icon,color = color,prefix = 'fa'),
popup=folium.Popup(html=landmark_popup_html, max_width=400),
tooltip=row['name'])
# Add the marker to the map
landmark_marker.add_to(marker_group)
# Create a legend
legend_html = """
<div style="position: fixed;
bottom: 50px; left: 50px; width: 500px; height: 50px;
border:2px solid grey; font-size:4px;
background-color: white;">
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-church" style="color:blue"></i> Church</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-synagogue" style="color:gray"></i> Synagogue</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-bus" style="color:green"></i> Transport</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-football-ball" style="color:orange"></i> Major Sports & Recreation Facility</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-graduation-cap" style="color:green"></i> Primary Schools</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-tree" style="color:green"></i> Informal Outdoor Facility (Park/Garden/Reserve)</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-graduation-cap" style="color:green"></i> Secondary Schools</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-theater-masks" style="color:red"></i> Theatre Live</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:gray"></i> Retail/Office</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:red"></i> Private Hospital</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-university" style="color:darkpurple"></i> Government Building</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-train" style="color:black"></i> Railway Station</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cubes" style="color:gray"></i> Vacant Land - Undeveloped Site</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i> Retail/Office/Carpark</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-palette" style="color:red"></i> Art Gallery/Museum</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i> Office</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-film" style="color:lightblue"></i> Film & RV Studio</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-anchor" style="color:blue"></i> Marina</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:red"></i> Public Hospital</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hotel" style="color:black"></i> Hostel</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paw" style="color:green"></i> Outdoor Recreation Facility (Zoo, Golf Course)</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-house" style="color:darkpurple"></i> Public Buildings</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-university" style="color:darkpurple"></i> University</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-fire-extinguisher" style="color:red"></i> Fire Station</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-eye" style="color:gray"></i> Observation Tower/Wheel</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-home" style="color:black"></i> Dwelling (House)</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-shield" style="color:red"></i> Police Station</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-football-ball" style="color:orange"></i> Private Sports Club/Facility</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-briefcase" style="color:red"></i> Function/Conference/Exhibition Centre</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-helmet-safety" style="color:gray"></i> Current Construction Site</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-book" style="color:darkpurple"></i> Further Education</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cube" style="color:orange"></i> Indoor Recreation Facility</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:gray"></i> Store Yard</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:gray"></i> Retail/Office/Residential/Carpark</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-dumbbell" style="color:orange"></i> Gymnasium/Health Club</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-building" style="color:black"></i> Retail/Residential</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-info-circle" style="color:gray"></i> Visitor Centre</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-book" style="color:purple"></i> Library</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cemetery" style="color:gray"></i> Cemetery</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-cross" style="color:blue"></i> Retail</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-school" style="color:orange"></i> School - Primary and Secondary Education</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-dice" style="color:red"></i> Casino</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-helmet-safety" style="color:darkblue"></i> Current Construction Site - Commercial</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-film" style="color:green"></i> Cinema</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-industry" style="color:black"></i> Industrial (Manufacturing)</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-water" style="color:darkgreen"></i> Aquarium</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-road-bridge" style="color:pink"></i> Bridge</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-store" style="color:cadetblue"></i> Department Store</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-hospital" style="color:lightred"></i> Medical Services</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paint-brush" style="color:darkpurple"></i> Art</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkgreen"></i> Monument</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-volcano" style="color:lightblue"></i> Fountain</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkred"></i> Memorials</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-landmark" style="color:purple"></i> Sculpture</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-snowflake" style="color:darkgreen"></i> Aurora Sculpture</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-monument" style="color:darkred"></i> Memorial</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-bell" style="color:darkpurple"></i> Federation Bells</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-shield-virus" style="color:orange"></i> Indigenous</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-comment-alt" style="color:gray"></i> Speakers Corner</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-clock" style="color:black"></i> Horology</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-question" style="color:gray"></i> Unknown</p>
<p style="margin:10px; display:inline-block;"><i class="fa-solid fa-paint-brush" style="color:darkpurple"></i> Artwork Commission</p>
</div>
"""
# Add the feature group to the map
marker_group.add_to(melbourne_map)
cafe_group.add_to(melbourne_map)
folium.LayerControl().add_to(melbourne_map)
# Add the legend to the map
legend = folium.plugins.FloatImage(legend_html, bottom=80, left=50)
legend.add_to(melbourne_map)
<folium.plugins.float_image.FloatImage at 0x7f9e1096c610>
# Display the map
melbourne_map